<template>
  <div class="upload-container">
    <h2 class="section-title">📤 文件上传</h2>
    
    <div class="upload-area">
      <div 
        class="drop-zone" 
        :class="{ 'drag-over': isDragging, 'uploading': isUploading }"
        @drop.prevent="handleDrop"
        @dragover.prevent="isDragging = true"
        @dragleave.prevent="isDragging = false"
      >
        <input 
          ref="fileInput" 
          type="file" 
          @change="handleFileSelect" 
          style="display: none"
        />
        
        <div v-if="!isUploading" class="drop-zone-content">
          <svg class="upload-icon" viewBox="0 0 24 24" fill="none">
            <path d="M12 3V15M12 3L8 7M12 3L16 7" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
            <path d="M3 15V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V15" stroke="currentColor" stroke-width="2"/>
          </svg>
          <p class="drop-text">拖放文件到此处或</p>
          <button @click="$refs.fileInput.click()" class="select-btn">
            选择文件
          </button>
          <p class="drop-hint">支持任意文件类型，最大 1GB</p>
        </div>
        
        <div v-else class="uploading-content">
          <div class="spinner"></div>
          <p class="uploading-text">正在上传和分片...</p>
          <p class="uploading-hint">{{ selectedFile?.name }}</p>
        </div>
      </div>
    </div>

    <div v-if="uploadedFiles.length > 0" class="uploaded-files">
      <h3 class="uploaded-title">已上传的文件 ({{ uploadedFiles.length }})</h3>
      
      <div class="file-list">
        <div 
          v-for="file in uploadedFiles" 
          :key="file.fileId"
          class="file-card"
        >
          <div class="file-header">
            <div class="file-icon">📄</div>
            <div class="file-info">
              <h4 class="file-name">{{ file.filename }}</h4>
              <p class="file-meta">
                {{ formatSize(file.size) }} · {{ file.shardCount }} 分片 · 
                <span class="rs-tag">RS {{ file.rsConfig.dataShards }},{{ file.rsConfig.parityShards }}</span>
              </p>
              <p class="file-date">{{ formatDate(file.uploadedAt) }}</p>
            </div>
            <button @click="deleteFile(file.fileId)" class="delete-btn" title="删除">
              <svg viewBox="0 0 24 24" fill="none">
                <path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2"/>
              </svg>
            </button>
          </div>
          
          <div class="file-links">
            <div class="link-group">
              <label>P2P 下载链接</label>
              <div class="link-box">
                <input 
                  :value="file.p2pLink" 
                  readonly 
                  class="link-input"
                  @click="$event.target.select()"
                />
                <button @click="useP2PLink(file.p2pLink)" class="use-btn">
                  使用此链接
                </button>
              </div>
            </div>
            
            <div class="link-group">
              <label>直接下载链接</label>
              <div class="link-box">
                <input 
                  :value="file.directLink" 
                  readonly 
                  class="link-input"
                  @click="$event.target.select()"
                />
                <button @click="useDirectLink(file.directLink)" class="use-btn">
                  使用此链接
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';

const emit = defineEmits(['use-link']);

const SERVER_URL = 'http://localhost:3000';

const fileInput = ref(null);
const selectedFile = ref(null);
const isDragging = ref(false);
const isUploading = ref(false);
const uploadedFiles = ref([]);

const handleFileSelect = (event) => {
  const file = event.target.files[0];
  if (file) {
    uploadFile(file);
  }
};

const handleDrop = (event) => {
  isDragging.value = false;
  const file = event.dataTransfer.files[0];
  if (file) {
    uploadFile(file);
  }
};

const uploadFile = async (file) => {
  selectedFile.value = file;
  isUploading.value = true;
  
  try {
    const formData = new FormData();
    formData.append('file', file);
    
    const response = await axios.post(`${SERVER_URL}/upload`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });
    
    if (response.data.success) {
      alert(`✅ 上传成功！\n\n文件: ${response.data.filename}\n大小: ${formatSize(response.data.size)}\n分片: ${response.data.shardCount}`);
      await loadUploadedFiles();
    }
  } catch (error) {
    alert(`❌ 上传失败: ${error.message}\n\n请确保服务器已启动: npm run server`);
  } finally {
    isUploading.value = false;
    selectedFile.value = null;
    if (fileInput.value) {
      fileInput.value.value = '';
    }
  }
};

const loadUploadedFiles = async () => {
  try {
    const response = await axios.get(`${SERVER_URL}/files`);
    uploadedFiles.value = response.data.files.sort((a, b) => 
      new Date(b.uploadedAt) - new Date(a.uploadedAt)
    );
  } catch (error) {
    console.error('加载文件列表失败:', error);
  }
};

const deleteFile = async (fileId) => {
  if (!confirm('确定要删除这个文件吗？')) return;
  
  try {
    await axios.delete(`${SERVER_URL}/files/${fileId}`);
    await loadUploadedFiles();
  } catch (error) {
    alert('删除失败: ' + error.message);
  }
};

const copyToClipboard = (text) => {
  navigator.clipboard.writeText(text).then(() => {
    alert('✅ 已复制到剪贴板');
  });
};

const useP2PLink = (link) => {
  emit('use-link', { link, type: 'p2p' });
};

const useDirectLink = (link) => {
  emit('use-link', { link, type: 'direct' });
};

const formatSize = (bytes) => {
  if (!bytes) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB'];
  const k = 1024;
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + units[i];
};

const formatDate = (date) => {
  return new Date(date).toLocaleString('zh-CN');
};

onMounted(() => {
  loadUploadedFiles();
});
</script>

<style scoped>
.upload-container {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  border-radius: 1rem;
  padding: 1.5rem;
  margin-bottom: 2rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.section-title {
  font-size: 1.25rem;
  font-weight: 700;
  margin: 0 0 1.5rem 0;
  color: #e0e0e0;
}

.upload-area {
  margin-bottom: 2rem;
}

.drop-zone {
  border: 2px dashed rgba(0, 212, 255, 0.3);
  border-radius: 0.75rem;
  padding: 3rem 2rem;
  text-align: center;
  transition: all 0.3s ease;
  background: rgba(0, 0, 0, 0.2);
}

.drop-zone.drag-over {
  border-color: #00d4ff;
  background: rgba(0, 212, 255, 0.1);
  transform: scale(1.02);
}

.drop-zone.uploading {
  border-color: rgba(123, 47, 247, 0.5);
  background: rgba(123, 47, 247, 0.1);
}

.drop-zone-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.upload-icon {
  width: 4rem;
  height: 4rem;
  color: #00d4ff;
  margin-bottom: 0.5rem;
}

.drop-text {
  font-size: 1.125rem;
  color: #e0e0e0;
  margin: 0;
}

.select-btn {
  padding: 0.75rem 2rem;
  background: linear-gradient(135deg, #00d4ff 0%, #0099cc 100%);
  border: none;
  border-radius: 0.5rem;
  color: white;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.select-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 212, 255, 0.4);
}

.drop-hint {
  font-size: 0.875rem;
  color: #a0a0a0;
  margin: 0;
}

.uploading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.spinner {
  width: 3rem;
  height: 3rem;
  border: 4px solid rgba(123, 47, 247, 0.2);
  border-top-color: #7b2ff7;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.uploading-text {
  font-size: 1.125rem;
  color: #e0e0e0;
  margin: 0;
}

.uploading-hint {
  font-size: 0.875rem;
  color: #a0a0a0;
  margin: 0;
}

.uploaded-files {
  margin-top: 2rem;
}

.uploaded-title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 1rem 0;
  color: #e0e0e0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.file-card {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 0.75rem;
  padding: 1.25rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.file-card:hover {
  border-color: rgba(0, 212, 255, 0.3);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.file-header {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  align-items: flex-start;
}

.file-icon {
  font-size: 2rem;
  flex-shrink: 0;
}

.file-info {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-size: 1rem;
  font-weight: 600;
  margin: 0 0 0.5rem 0;
  color: #e0e0e0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-meta {
  font-size: 0.875rem;
  color: #a0a0a0;
  margin: 0 0 0.25rem 0;
}

.rs-tag {
  color: #b794f6;
  background: rgba(123, 47, 247, 0.2);
  padding: 0.125rem 0.5rem;
  border-radius: 0.25rem;
  font-size: 0.75rem;
}

.file-date {
  font-size: 0.75rem;
  color: #707070;
  margin: 0;
}

.delete-btn {
  width: 2rem;
  height: 2rem;
  border: none;
  background: rgba(255, 68, 68, 0.1);
  color: #ff4444;
  border-radius: 0.375rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.delete-btn:hover {
  background: rgba(255, 68, 68, 0.2);
}

.delete-btn svg {
  width: 1rem;
  height: 1rem;
}

.file-links {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.link-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.link-group label {
  font-size: 0.75rem;
  color: #a0a0a0;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}

.link-box {
  display: flex;
  gap: 0.5rem;
}

.link-input {
  flex: 1;
  padding: 0.625rem 0.875rem;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.375rem;
  color: #00d4ff;
  font-size: 0.8125rem;
  font-family: 'Courier New', monospace;
  cursor: text;
}

.link-input:focus {
  outline: none;
  border-color: #00d4ff;
}

.copy-btn, .use-btn {
  padding: 0.625rem 1rem;
  border: none;
  border-radius: 0.375rem;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.875rem;
  transition: all 0.3s ease;
}

.copy-btn {
  background: rgba(255, 255, 255, 0.1);
  color: #e0e0e0;
  min-width: 2.5rem;
}

.copy-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}

.use-btn {
  background: linear-gradient(135deg, #7b2ff7 0%, #5a1fb8 100%);
  color: white;
}

.use-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(123, 47, 247, 0.3);
}
</style>


